<?php
class SiteController extends BackOfficeController
{
    /**
    * DB connection to database the new site uses
    * @var CDbConnection
    */
    protected $db;
    
    /**
    * Site to be created
    * @var SiteInfo
    */
    protected $site;
    
    /**
    * ID in database of new row added into #_site table
    * @var int
    */
    protected $siteId;
    
    public function actionCreate()
    {
        $domain = str_replace('.admin.','.',parse_url(Yii::app()->request->getHostInfo(), PHP_URL_HOST));
        $domainParts = explode('.',$domain);
        if (count($domainParts)==3)
        {
            unset($domainParts[0]);
            $domain = implode('.',$domainParts);
        }
        
        // each time, we create only one site
        $this->site = SiteInfo::model()->find(new CDbCriteria(array('condition'=>'is_created = false','order'=>'id ASC')));
        
        if (empty($this->site)) {
            echo 'No site has to be created.';
            return;
        }

        echo "Creating site ",$this->site->sub_domain,".indition.com\n";
    
        // 1. Environment file
        $this->createEnvFile($domain);
        // 2. Folder structure for custom code and runtime and themes
        $this->createFolderStructure();        
        // 3. Initial data
        
        $user_site_prefix = strtolower($this->SiteUsername).'_'.strtolower(str_replace('-','_',$this->site->sub_domain)).'_';
        $user_prefix = strtolower($this->SiteUsername).'_';
        // 3.1 static data
        include Yii::getPathOfAlias('SiteManagement.components').'/initial_data_static.php';
        
        $tables = $this->db->schema->tableNames;
        // check table #_site exists
        if (!in_array($user_prefix.'site',$tables))
        {
            $sqls[] = '
                CREATE TABLE "public"."'.$user_prefix.'site" (
                "id" serial NOT NULL,
                "name" varchar(100) NOT NULL,
                "status" bool,
                "default" bool,
                "creation_datetime" timestamp(6),
                "last_update" timestamp(6),
                "locale_id" varchar(20),
                "company_name" varchar(255),
                "company_email" varchar(255),
                "about_us" text,
                "address" varchar(255),
                "city" varchar(128),
                "state" varchar(128),
                "zipcode" varchar(16),
                "country" varchar(128),
                "phone" varchar(32),
                "subdomain" varchar(128)
                )
                WITH (OIDS=FALSE);
            ';
            $sqls[] = 'ALTER TABLE public.'.$user_prefix.'site ADD PRIMARY KEY ("id");';    
        }
        // check table #_site_url exists
        if (!in_array($user_prefix.'site_url',$tables))
        {
            $sqls[] = '
                CREATE TABLE "public"."'.$user_prefix.'site_url" (
                "id" serial NOT NULL,
                "site_id" int8 NOT NULL,
                "url" varchar(100) NOT NULL,
                "status" bool,
                "default" bool,
                "creation_datetime" timestamp(6),
                "last_update" timestamp(6)
                )
                WITH (OIDS=FALSE);
            ';
            $sqls[] = 'ALTER TABLE public.'.$user_prefix.'site_url ADD PRIMARY KEY ("id");';        
        }
        
        foreach($sqls as $sql)
        {
            $result = $this->db->createCommand($sql)->execute();
        }
        
        // insert to table #_site first to get last insert id
        $sql_insert_site = "INSERT INTO public.".$user_prefix."site (name,status,creation_datetime,last_update,locale_id,company_name,company_email,about_us,address,city,state,zipcode,country,phone,subdomain) VALUES (
                '".str_replace("'",'"',$this->site->site_name)."',
                't',
                '".$current_datetime."',
                null,
                'en_us',
                '".str_replace("'",'"',$this->site->contact_company_name)."',
                '".str_replace("'",'"',$this->site->contact_company_email)."',
                '".str_replace("'",'"',$this->site->about_us)."',
                '".str_replace("'",'"',$this->site->contact_address)."',
                '".str_replace("'",'"',$this->site->contact_city)."',
                '".str_replace("'",'"',$this->site->contact_state)."',
                '".str_replace("'",'"',$this->site->contact_zipcode)."',
                '',
                '".str_replace("'",'"',$this->site->contact_phone)."',
                '".str_replace("'",'"',$this->site->sub_domain)."'
            );
        ";
        $result = $this->db->createCommand($sql_insert_site)->execute();
        $this->siteId = $this->db->getLastInsertID($user_prefix.'site_id_seq');

        // 3.2 Dynamic data required site_id
        include Yii::getPathOfAlias('SiteManagement.components').'/initial_data_dynamic.php';
        
        foreach($sqls_insert as $sql)
        {
            $result = $this->db->createCommand($sql)->execute();
        }
        
        // 4. Themes
        $this->createTheme();
        
        // 5. Finalizing
        $this->site->is_created = true;
        $this->site->update(array('is_created'));
        
        Yii::app()->db->schema->refresh();
        
        echo "username [{$this->SiteUsername}] - site {$this->site->sub_domain} has been created<br />"; 
    }
    
    protected function getSiteUsername(){
        return str_replace(array('.','_','-'),'',$this->site->user->username);
    }
        
    protected function createEnvFile($domain){
        $env_filename = 'config.'.$this->site->sub_domain.'.'.$domain.'.php';
        // create content for env file name
        
        // todo: the db connection might not be the same with Yii::app()->db
        
        $env_file_content = "
<?php\n
define('SITE_DIR','".$this->site->folder."'.DIRECTORY_SEPARATOR.'".$this->SiteUsername."'.DIRECTORY_SEPARATOR.'".$this->site->sub_domain."');\n
define('SITE_USER','".strtolower($this->SiteUsername)."');\n
define('SITE_TABLE_PREFIX','".strtolower($this->SiteUsername)."_".strtolower(str_replace('-','_',$this->site->sub_domain))."_');\n 
\$dbs = array();\n
\$dbs['default']['connectionString'] = '".Yii::app()->db->connectionString."';\n
\$dbs['default']['username'] = '".Yii::app()->db->username."';\n
\$dbs['default']['password'] = '".Yii::app()->db->password."';\n
?>
        ";
        $env_filename_path = Yii::getPathOfAlias('sites').'/env/'.$env_filename;
        file_put_contents($env_filename_path,$env_file_content);        
        
        $this->db = Yii::app()->db;
    }
    
    protected function createFolderStructure() {
        $baseDir = Yii::getPathOfAlias('sites');
        
        // root folder of this site
        if (!file_exists(Yii::getPathOfAlias('sites').'/'.$this->site->folder))
            mkdir($baseDir.'/'.$this->site->folder);
        if (!file_exists($baseDir.'/'.$this->site->folder.'/'.$this->SiteUsername))
            mkdir($baseDir.'/'.$this->site->folder.'/'.$this->SiteUsername);
        $siteFolderPath = $baseDir.'/'.$this->site->folder.'/'.$this->SiteUsername.'/'.$this->site->sub_domain;
        if (!file_exists($siteFolderPath))
            mkdir($siteFolderPath);
            
        // folder structure
        $customSiteFolders = array(
            'assets' => 0777,
            'protected' => 0777,
            'protected/Site' => 0777,
            'protected/runtime' => 0777,
            'protected/runtime/cache' => 0777,
            'uploads' => 0777,
            'themes' => 0777,    
        );

        foreach($customSiteFolders as $folder_path => $permission)
        {
            $folder_path = $siteFolderPath.'/'.$folder_path;
            if (!file_exists($folder_path))
                mkdir($folder_path,$permission);    
        }        
        
        // default Site module
        $source = Yii::getPathOfAlias('sites').'/0/Tagrem/indition/protected/Site/';
        smartCopy($source, $siteFolderPath.'/protected/Site/');
        
        // modules.php in runtime
        $config = array();
        if (!empty($this->site->modules)){
            $modules = unserialize($this->site->modules);
            $modules[] = 'Site';
        }else{
            $modules = array('Site');
        }
            
        if (is_array($modules) && count($modules) > 0) {
            foreach($modules as $key => $module)
            {
                $mConfig = array(
                    //'class' => "site.{$module->name}.{$module->name}Module",
                );
                // todo: load module config into $mConfig
                
                $config[$module] = $mConfig;
            }
        }    
        
        $str = '<?php return '.var_export($config, true).'; ?>';
        file_put_contents($siteFolderPath.'/protected/runtime/modules.php',$str);
    }
    
    protected function createTheme(){
        $theme = empty($this->site->template) ? 'blank' : $this->site->template;
        $themeDir = Yii::getPathOfAlias('sites').'/0/Tagrem/indition/themes/'.$theme;
        
        if (!is_dir($themeDir))
            throw new CException("Theme {$theme} is not found to copy.");
            
        // copy theme
        $baseDir = Yii::getPathOfAlias('sites');
        $siteFolderPath = $baseDir.'/'.$this->site->folder.'/'.$this->SiteUsername.'/'.$this->site->sub_domain;
        smartCopy($themeDir, $siteFolderPath.'/themes/');
        // load data
        $user_site_prefix = strtolower($this->SiteUsername).'_'.strtolower(str_replace('-','_',$this->site->sub_domain)).'_';
        $user_prefix = strtolower($this->SiteUsername).'_';
        include $themeDir.'/meta/data.php';
        
        foreach($sqls_insert as $sql)
        {
            $result = $this->db->createCommand($sql)->execute();
        }        
    }
}
?>
